数据库同步 Sample详情
最后更新时间:2019年7月5日
数据库同步编辑,即涉及基于整个地图或部分图层数据的下载、更新、提交操作。首先,可以将IGServer服务器上发布的地图服务数据进行下载存储为移动端本地数据库;下载完成之后,当服务器上发布的地图要素发生变化时,可对本地离线数据库进行更新操作;当本地离线数据库中的要素发生变化时,也可将其提交到IGServer服务器中进行同步。
用户可以将IGServer服务器上发布的地图文档中某一个地图下载到本地,也可下载一个地图的部分图层,甚至可以对下载的图层设置下载范围和属性条件,下载的地图数据存储为移动端离线数据库(即“*.mgdb”的数据库),离线数据库名称与下载的地图文档名称一致。
需要注意的是:下载数据时,要保证程序运行的网络流畅,如果网络速度较慢或者网络情况不佳的话,下载速度会比较慢,也有可能下载失败。
数据库同步编辑下载,基于地图的图层数范围与要素筛选条件方式,可以分为以下几种方式,如图所示。
数据库同步下载功能实现的关键步骤如下图所示:
1
获取下载数据信息,可通过登录IGServer服务管理器直接查看,也可通过代码方式获取;
//在线数据:服务基地址、图层URL、地图文档名称、地图ID NSString *igserverBaseURL = @"http://develop.smaryun.com:6163/igs"; NSString *layerURL = @"gdbp://MapGisLocal/武汉MKT/sfcls/四级点"; NSString *docName = @"WuHan"; int mapID = 0; //获取要下载的地图服务信息对象(服务基地址、地图名称、地图ID) MGSMapServiceInfo *mapServiceInfo=[MGSDataBaseSync getMapServiceInfoWithIGServerBaseURL:self.igserverBaseURL docName:self.docName mapID:0]; //获取地图服务的图层列表 NSArray<MGSMapServiceLayerInfo *> *serviceLayerInfoArr=[_mapServiceInfo getLayerInfos]; //根据图层信息可获取图层名称、图层ID。可在下载之前展示给用户 NSString *name = serviceLayerInfoArr[0].name; NSString *layerID = serviceLayerInfoArr[0].layerID;
2
构造下载参数(MGSDownloadDataBaseParmeters)。
//创建默认的下载数据参数(参数:地图服务基地址、地图文档名称、地图ID、范围) MGSDownloadDataBaseParmeters *downloadDBParameters=[MGSDataBaseSync createDefaultDownloadDataBaseParmetersWithIGServerBaseURL:self.igserverBaseURL docName:self.docName mapID:0 extent:[[_mapView map] range]];
3
SDK提供多种条件的数据下载模式,在下载之前不同的模式需设置不同的条件。
[downloadDBParameters removeLayer:1]; //参数:图层ID
[downloadDBParameters setExtent:MGSRectMake(xMin,yMin, xMax,yMax)];
//从下载参数中获取下载图层选项 NSArray<MGSDownloadLayerOption *> *layerOptionArray = [_downloadDBParameters getLayerOptions]; //获取某一图层的下载参数,设置属性条件 MGSDownloadLayerOption *layerOption=[layerOptionArray objectAtIndex:i]; [layerOption setWhereClause:@"Name LIKE '%公园%'"];
4
调用数据库同步编辑对象的方法执行下载。
//数据库保存路径 NSString *savePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]stringByAppendingPathComponent:@"MapGIS Mobile 2D Sample/Download/"]; //下载(服务基地址、地图名称、地图ID、下载数据参数、路径)(保存为数据库.mgdb) long downCode=[MGSDataBaseSync downloadASyncWithIGServerBaseURL:self.igserverBaseURL docName:self.docName mapID:0 params:downloadDBParameters path:savePath];
说明:
(1)下载方法为静态方法,直接使用类名调用即可。
(2)下载方法是异步方法,并附带监听,不需要用户开启子线程。
(3)返回结果代表下载编号,可以支持多任务并发执行。
(4)如果下载过程中需要停止,可以调用stopASyncWithSyncCode:方法,同样适用于后续的更新、提交操作。
5
首先需要为ViewController遵守下载进度回调、下载结果回调代理协议,然后为数据库同步类设置代理,最后实现其回调函数,获取进度、结果信息。
@interface DataBaseSync_ViewController ()<ProgressListener,FinishedListener> //为数据库同步设置进度监听:包括下载、更新、提交 [MGSDataBaseSync setProgressListener:self]; //为数据库同步设置结果监听:包括下载、更新、提交 [MGSDataBaseSync setFinishedListener:self];
下载进程回调监听(非主线程):
-(void)onProgressWithSyncCode:(long)lSyncCode totleClsCount:(long)totalClsCount curClsIndex:(long)curClsIndex curClsUpdateProgress:(double)curClsUpdateProgress{ if (lSyncCode == _downCode) { //判断下载任务编号 NSLog(@"下载任务编号:%ld\n图层总数:%ld\n当前图层ID:%ld\n下载进度:%.2f%%",_downCode,totalClsCount,curClsIndex,curClsUpdateProgress); } }
下载结果回调监听(非主线程):
-(void)onFinishedWithSyncCode:(long)lSyncCode success:(BOOL)normalSuccessed{ if (lSyncCode == _downCode) { if (normalSuccessed) { NSLog(@"下载成功!"); } else { NSLog(@"下载失败!"); } } }
6
数据下载完成后,保存为Database数据库,可以使用MGSDatabase对象的getXclsInfo方法获取要素类,然后创建矢量图层对象MGSVectorLayer,进行显示。
更新操作,是针对已经从服务器上下载、保存到移动端本地中的数据库。如果IGServer中发布的地图发生变化,想对已经下载的离线数据库进行数据的同步,则可以不用再次下载整个地图数据,直接利用更新操作将移动端本地数据库进行更新。减少了离在线数据同步的数据量,节约时间。
数据库同步编辑更新和要素同步编辑更新类似,功能实现的关键步骤如下:
1
//下载的数据库路径 NSString *dataBasePath= [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]stringByAppendingPathComponent:@"/MapGIS Mobile 2D Sample/Download/WuHan/WuHan.mgdb"]; //创建数据库对象 MGSDataBase *dataBase=[[MGSDataBase alloc] init]; //打开数据库 [dataBase open:dataBasePath];
2
//根据数据库创建同步数据参数 MGSSyncDataBaseParmeters *syncDBParmters=[MGSDataBaseSync createDefaultSyncDataBaseParmetersWithDataBase:self.dataBase];
3
用户可以选择只更新部分图层。
//部分图层更新,通过同步图层参数移除不参与更新的图层 [syncparmeters removeLayer:1]; //参数:图层ID
4
进行实际的数据更新操作。更新操作同样是异步操作,不需用户开启子线程。
//更新(参数:同步参数、数据库) long updateCode=[MGSDataBaseSync updateASyncWithParams:syncDBParmters database:self.dataBase];
5
与下载操作一样,具有监听器可以监听更新的进度、结果信息,并且调用的接口也一致。
更新进度监听:
-(void)onProgressWithSyncCode:(long)lSyncCode totleClsCount:(long)totalClsCount curClsIndex:(long)curClsIndex curClsUpdateProgress:(double)curClsUpdateProgress{ if (lSyncCode == _updateCode) { //判断更新任务编号 NSLog(@"更新任务编号:%ld\n图层总数:%ld\n当前图层ID:%ld\n更新进度:%.2f%%",_updateCode,totalClsCount,curClsIndex,curClsUpdateProgress); } }
更新结果监听:
-(void)onFinishedWithSyncCode:(long)lSyncCode success:(BOOL)normalSuccessed{ if (lSyncCode == _updateCode) { //判断更新任务编号 if (normalSuccessed) { NSLog(@"更新成功!"); } else { NSLog(@"更新失败!"); } } }
6
在对离线数据更新完成之后,需要重新读取Database中的数据进行展示才能看到效果。
提交操作,是针对已经从服务器上下载、保存到移动端本地中的数据库。适用情况:如果已下载的移动端本地数据库中数据发生变化,例如对离线数据库中的要素进行了编辑,此时想对IGServer服务器中发布的地图进行同步,则可以利用提交操作将数据库中的全部图层或部分变更图层数据提交到IGServer服务器中。
数据库同步编辑提交和要素同步编辑提交类似,其实现的关键步骤和更新类似。
1
//下载的数据库路径 NSString *dataBasePath= [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]stringByAppendingPathComponent:@"/MapGIS Mobile 2D Sample/Download/WuHan/WuHan.mgdb"]; //创建数据库对象 MGSDataBase *dataBase=[[MGSDataBase alloc] init]; //打开数据库 [dataBase open:dataBasePath];
2
//根据数据库创建同步数据参数 MGSSyncDataBaseParmeters *syncDBParmters=[MGSDataBaseSync createDefaultSyncDataBaseParmetersWithDataBase:self.dataBase];
3
用户可以选择只提交部分图层。
//部分图层提交,通过同步图层参数移除不参与提交的图层 [syncparmeters removeLayer:1]; //参数:图层ID
4
调用commitASync进行实际的数据提交操作。提交操作同样是异步操作,不需用户开启子线程。
//提交(参数:同步参数、数据库) long commitCode=[MGSDataBaseSync commitASyncWithParams:syncDBParmters database:self.dataBase];
5
与下载、更新操作一样,具有监听器可以监听提交的进度、结果信息,并且调用的接口也一致。
提交进度监听:
-(void)onProgressWithSyncCode:(long)lSyncCode totleClsCount:(long)totalClsCount curClsIndex:(long)curClsIndex curClsUpdateProgress:(double)curClsUpdateProgress{ if (lSyncCode == _commitCode) { //判断提交任务编号 NSLog(@"提交任务编号:%ld\n图层总数:%ld\n当前图层ID:%ld\n提交进度:%.2f%%",_commitCode,totalClsCount,curClsIndex,curClsUpdateProgress); } }
提交结果监听:
-(void)onFinishedWithSyncCode:(long)lSyncCode success:(BOOL)normalSuccessed{ if (lSyncCode == _commitCode) { //判断提交任务编号 if (normalSuccessed) { NSLog(@"提交成功!"); } else { NSLog(@"提交失败!"); } } }
6
在对离线数据更新完成之后,需要重新读取Database中的数据进行展示才能看到效果。